﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.LightSwitch;
using Microsoft.LightSwitch.Security.Server;
using System.Linq.Expressions;

namespace LightSwitchApplication
{
    public partial class SalesDepDataService
    {
        //partial void SalesOrdersForSearch_PreprocessQuery(Guid? aspnet_Profile_UserId, string FilterTerm, ref IQueryable<SalesOrder> query)
        //{
        //    query = FilterControl.FilterExtensions.Filter(query, FilterTerm, this.Application);
        //}


        partial void SaveChanges_Executing()
        {
            EntityChangeSet changes = this.DataWorkspace.SalesDepData.Details.GetChanges();

            foreach (var item_loopVariable in changes.ModifiedEntities)
            {
                //IEntityObject item = item_loopVariable as IEntityObject;
                setModifiedInfo(item_loopVariable);
                createAuditTrail(item_loopVariable);
            }

            foreach (var item_loopVariable in changes.AddedEntities)
            {
                //IEntityObject item = item_loopVariable as IEntityObject;
                setCreatedInfo(item_loopVariable);
                createAuditTrail(item_loopVariable);
            }

            foreach (var item_loopVariable in changes.DeletedEntities)
            {
                //IEntityObject item = item_loopVariable as IEntityObject;
                createAuditTrail(item_loopVariable);
            }
        }

        private void setCreatedInfo(IEntityObject item)
        {

            foreach (var prop_loopVariable in item.Details.Properties.All().OfType<Microsoft.LightSwitch.Details.IEntityStorageProperty>().Where(x => x.Name.StartsWith("Created")))
            {
                //IEntityStorageProperty prop = prop_loopVariable as IEntityStorageProperty;
                if (prop_loopVariable.Name == "CreatedDate")
                {
                    prop_loopVariable.Value = DateTime.Now;
                }

                if (prop_loopVariable.Name == "CreatedBy")
                {
                    prop_loopVariable.Value = this.Application.User.Name;
                }
            }
        }

        private void setModifiedInfo(IEntityObject item)
        {

            foreach (var prop_loopVariable in item.Details.Properties.All().OfType<Microsoft.LightSwitch.Details.IEntityStorageProperty>().Where(x => x.Name.StartsWith("Modified")))
            {
                //IEntityStorageProperty prop = prop_loopVariable as IEntityStorageProperty;
                if (prop_loopVariable.Name == "ModifiedDate")
                {
                    prop_loopVariable.Value = DateTime.Now;
                }

                if (prop_loopVariable.Name == "ModifiedBy")
                {
                    prop_loopVariable.Value = this.Application.User.Name;
                }
            }

        }

        private void createAuditTrail(IEntityObject item)
        {
            dynamic audit = this.DataWorkspace.SalesDepData.AuditLogs.AddNew();
            audit.EntityId = 0;
            audit.EntityName = item.Details.DisplayName;
            audit.ChangeDate = DateTime.Now;
            audit.ChangedBy = this.Application.User.FullName;
            audit.ChangeType = (item.Details.EntityState.ToString() == "Added" ? "Вставка" :
                (item.Details.EntityState.ToString() == "Modified" ? "Изменение" :
                    (item.Details.EntityState.ToString() == "Deleted" ? "Удаление" :
                        item.Details.EntityState.ToString())));

            dynamic newvals = "\n";
            dynamic oldvals = "\n";

            if (item.Details.EntityState == EntityState.Deleted)
            {
                oldvals = string.Format("\n{0} {1}:", item.Details.DisplayName, item.Details.EntityState);
            }
            else if (item.Details.EntityState == EntityState.Added)
            {
                newvals = string.Format("\n{0} {1}:", item.Details.DisplayName, item.Details.EntityState);
            }
            bool isAuditableEntity = false;
            foreach (var prop in item.Details.Properties.All().OfType<Microsoft.LightSwitch.Details.IEntityTrackedProperty>().Where(x => x.Name != "Id" && x.Name != "ModifiedDate" && x.Name != "ModifiedBy" && (!x.Name.Contains("Image"))))
            {
                isAuditableEntity = true;
                //prop = prop_loopVariable;
                if (item.Details.EntityState == EntityState.Modified)
                {
                    if (!object.Equals(prop.Value, prop.OriginalValue))
                    {
                        oldvals += string.Format("\n{0}: {1}", prop.DisplayName, prop.OriginalValue);
                        newvals += string.Format("\n{0}: {1}", prop.DisplayName, prop.Value);
                    }
                }
                else if (item.Details.EntityState == EntityState.Added)
                {
                    newvals += string.Format("\n{0}: {1}", prop.DisplayName, prop.Value);
                }
                else
                {
                    oldvals += string.Format("\n{0}: {1}", prop.DisplayName, prop.Value);
                }
            }
            if (isAuditableEntity)
            {
                var prop_Id = item.Details.Properties.All().OfType<Microsoft.LightSwitch.Details.IEntityTrackedProperty>().Where(x => x.Name == "Id").First();
                if (prop_Id != null)
                {
                    audit.EntityId = (Int32)prop_Id.Value;
                }

                if (item.Details.EntityState == EntityState.Added)
                {
                    audit.NewValues = newvals.Replace("\n\n", "");
                }
                else if (item.Details.EntityState == EntityState.Deleted)
                {
                    audit.OriginalValues = oldvals.Replace("\n\n", "");
                }
                else
                {
                    audit.OriginalValues = oldvals.Replace("\n\n", "");
                    audit.NewValues = newvals.Replace("\n\n", "");
                }
            }
        }

        partial void Addresses_Filter(ref Expression<Func<Address, bool>> filter)
        {
            if (!this.Application.User.HasPermission(Permissions.SecurityAdministration)) //if user has no one of these permissions it must be explicitly linked with contact
            {
                filter = e => e.Customer.aspnet_Profile.PropertyValuesString == this.Application.User.FullName;
            }
        }

        partial void Contacts_Filter(ref Expression<Func<Contact, bool>> filter)
        {
            if (!this.Application.User.HasPermission(Permissions.SecurityAdministration)) //if user has no one of these permissions it must be explicitly linked with contact
            {
                filter = e => e.ContactCustomer.aspnet_Profile.PropertyValuesString == this.Application.User.FullName;
            }
        }

        partial void Customers_Filter(ref Expression<Func<Customer, bool>> filter)
        {
            if (!this.Application.User.HasPermission(Permissions.SecurityAdministration)) //if user has no one of these permissions it must be explicitly linked with contact
            {
                filter = e => e.aspnet_Profile.PropertyValuesString == this.Application.User.FullName;
            }
        }

        partial void SalesOrders_Filter(ref Expression<Func<SalesOrder, bool>> filter)
        {
            if (!this.Application.User.HasPermission(Permissions.SecurityAdministration)) //if user has no one of these permissions it must be explicitly linked with contact
            {
                filter = e => e.OrderShop.ShopCustomer.aspnet_Profile.PropertyValuesString == this.Application.User.FullName;
            }
        }

        partial void Shops_Filter(ref Expression<Func<Shop, bool>> filter)
        {
            if (!this.Application.User.HasPermission(Permissions.SecurityAdministration)) //if user has no one of these permissions it must be explicitly linked with contact
            {
                filter = e => e.ShopCustomer.aspnet_Profile.PropertyValuesString == this.Application.User.FullName;
            }
        }


    }
}
